<?php

class Common_Debug 
{

    static public function debug($mix, $debugName = 'debug', $stackPosition = 0) {

        $debugBacktrace = debug_backtrace();

	$file = $debugBacktrace[$stackPosition]['file'];
	$lineNumber = $debugBacktrace[$stackPosition]['line'];
	$operation = '';

        $stackPosition++;

	if(isset($debugBacktrace[$stackPosition])) {
            
            $className = '';

            $methodName = $debugBacktrace[$stackPosition]['function'];
            $methodType = isset($debugBacktrace[$stackPosition]['type']) ? $debugBacktrace[$stackPosition]['type'] : '';

            if(isset($debugBacktrace[$stackPosition]['object'])) {
                $className = get_class($debugBacktrace[$stackPosition]['object']);
            } else if(isset($debugBacktrace[$stackPosition]['class'])) {
                $className = $debugBacktrace[$stackPosition]['class'];
            }

            $operation = $methodName . '()';
            if(!empty($className)) {
                $operation = $className . $methodType . $operation;
            }
            
	}

	$debug =  $file . ' [line ' . $lineNumber . ']';
	if(!empty($operation)) {
            $debug .= ' within '. $operation;
	}

	if(php_sapi_name() != 'cli') {
            echo '<div style="font-weight: bold; font-size: 130%;">' . 
                $debugName .
                ' <span style="font-weight: normal; font-size: 60%;">' .
                trim(self::type($mix) . ' ' . self::typeAttributes($mix)) .
                '</span></div>';
            echo '<div style="font-size: 80%">' . $debug . '</div>';
	    self::printr($mix);
	} else {
            echo "\n";
            echo trim($debugName . ' ' . self::type($mix) . ' ' . self::typeAttributes($mix)) . "\n";
            echo $debug . "\n";
	    self::printr($mix);
            echo "\n";
	}
    }

    static public function type($mix) {
        $output = '';
        if (is_null($mix)) {
            $output = '[n]';
        } else if (is_bool($mix)) {
            $output = '[b]';
        } else if (is_string($mix)) {
            $output = '[s]';
        } else if (is_int($mix)) {
            $output = '[i]';
        } else if (is_float($mix)) {
            $output = '[f]';
        } else if (is_array($mix)) {
            $output = '[a]';
        } else if (is_object($mix)) {
            $output = '[o]';
        } else if (is_resource($mix)) {
            $output = '[r]';
        }
        return $output;
    }

    static public function typeAttributes($mix) {
        $output = '';
        
        if (is_bool($mix)) {
            $output = ($mix) ? 'true' : 'false';
        } else if (is_string($mix)) {
            $int_length = strlen($mix);
            $output = 'length(' . $int_length . ')';
        } else if (is_array($mix)) {
            $output = 'array(' . count($mix) . ')';
        } else if (is_object($mix)) {
            $output = 'object(' . get_class($mix) . ')';
        } else if (is_resource($mix)) {
            $output = 'type(' . get_resource_type($mix) . ')';
        }

        return $output;
    }

    static public function printr($mix)
    {
	if (php_sapi_name() != 'cli') { 
            echo '<pre>';
        }
	print_r($mix);
	if (php_sapi_name() != 'cli') { 
            echo '</pre>';
        }
	if (php_sapi_name() == 'cli') { 
            echo "\n";
        }
    }

    static public function toPhpValue($mix, $indentation = 0)
    {
        $output = null;

        if (is_bool($mix)) {
            $output = ($mix) ? 'true' : 'false';
        } else if (is_numeric($mix)) {
            $output = $mix;
        } else if (is_string($mix)) {
            $output = "'" . $mix . "'";
        } else if (is_array($mix)) {
            $output = self::toPhpArray($mix, $indentation+1);
        }

        return $output;
    }

    static protected function toPhpArray($var, $indentation = 0)
    {
        if (is_array($var)) {

            $output = 'array(' . "\n";
            foreach ($var as $key => $value) {
                $output .= str_pad('', ($indentation * 4), ' ', STR_PAD_LEFT) . "'" . $key . "' => ";
                $output .= self::toPhpValue($value, $indentation);
                $output .= ",\n";
            }
            $output .= str_pad('', (($indentation-1) * 4), ' ', STR_PAD_LEFT) . ')';

        }

        return $output;
    }

}

function egg($mix, $debugName = 'debug') {
    Common_Debug::debug($mix, $debugName, 1);
}

function bacon($mix) {
    Common_Debug::debug($mix, 'die');
    die;
}
